package com.logos.musicframe.ui.javafx;

import com.alibaba.fastjson.JSON;
import com.logos.musicframe.constant.RedisConstant;
import com.logos.musicframe.controller.UsersController;
import com.logos.musicframe.req.UsersReq;
import com.logos.musicframe.result.Result;
import com.logos.musicframe.utils.RandomStringUtil;
import com.logos.musicframe.utils.RedisUtil;
import com.logos.musicframe.utils.SpringContextUtil;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.util.Duration;

/**
 * @author logos
 * date 2025/6/3 16:07
 * @version v1.0
 * @Package com.logos.musicframe.ui
 */
@Component
@Lazy
@Slf4j
public class RegisterFxUi extends Application {

    private TextField phoneField;
    private PasswordField passwordField, confirmPasswordField;

    private TextField captchaField;

    private Button registerButton, backToLoginButton, getCaptchaButton;
    private String currentCaptcha;

    private UsersController usersController = SpringContextUtil.getBean(UsersController.class);

    private RedisUtil redisUtil = SpringContextUtil.getBean(RedisUtil.class);

    @Override
    public void start(Stage primaryStage) throws Exception {
        // 初始化窗口设置
        primaryStage.setTitle("音乐播放器 - 注册");
        primaryStage.initStyle(StageStyle.TRANSPARENT); // 设置无边框窗口
        
        // 创建主容器
        BorderPane root = new BorderPane();
        root.setStyle("-fx-background-color: transparent;");
        
        // 创建卡片效果容器
        StackPane cardContainer = new StackPane();
        cardContainer.setPadding(new Insets(20));
        
        // 添加卡片背景
        Rectangle backgroundRect = new Rectangle(560, 700);
        backgroundRect.setArcWidth(20);
        backgroundRect.setArcHeight(20);
        backgroundRect.setFill(Color.WHITE);
        
        // 添加阴影效果
        DropShadow dropShadow = new DropShadow();
        dropShadow.setColor(Color.rgb(0, 0, 0, 0.2));
        dropShadow.setOffsetX(0);
        dropShadow.setOffsetY(5);
        dropShadow.setRadius(10);
        backgroundRect.setEffect(dropShadow);
        
        cardContainer.getChildren().add(backgroundRect);
        
        // 创建内容区域
        VBox contentBox = new VBox(20);
        contentBox.setAlignment(Pos.TOP_CENTER);
        contentBox.setPadding(new Insets(10, 30, 40, 30));
        contentBox.setMaxWidth(520);
        
        // 顶部控制栏（用于拖拽和关闭）
        HBox controlBar = new HBox();
        controlBar.setAlignment(Pos.BASELINE_RIGHT);
        controlBar.setPrefHeight(30);
        controlBar.setPrefWidth(520);
        controlBar.setPadding(new Insets(0, 5, 10, 0));
        
        // 填充空白区域，用于拖拽
        Region dragRegion = new Region();
        HBox.setHgrow(dragRegion, Priority.ALWAYS);
        
        // 关闭按钮
        Button closeButton = new Button("×");
        closeButton.setStyle(
            "-fx-background-color: transparent;" +
            "-fx-text-fill: #999999;" +
            "-fx-font-size: 20px;" +
            "-fx-font-weight: bold;" +
            "-fx-padding: 0 10 0 10;"
        );
        
        closeButton.setOnMouseEntered(e -> 
            closeButton.setStyle(
                "-fx-background-color: #ff5252;" +
                "-fx-text-fill: white;" +
                "-fx-font-size: 20px;" +
                "-fx-font-weight: bold;" +
                "-fx-padding: 0 10 0 10;"
            )
        );
        
        closeButton.setOnMouseExited(e -> 
            closeButton.setStyle(
                "-fx-background-color: transparent;" +
                "-fx-text-fill: #999999;" +
                "-fx-font-size: 20px;" +
                "-fx-font-weight: bold;" +
                "-fx-padding: 0 10 0 10;"
            )
        );
        
        // 关闭事件
        closeButton.setOnAction(e -> {
            primaryStage.close();
            // 确保应用程序完全退出
            Platform.exit();
            System.exit(0);
        });
        
        controlBar.getChildren().addAll(dragRegion, closeButton);
        
        // 用于拖拽窗口的变量
        final double[] xOffset = {0};
        final double[] yOffset = {0};
        
        // 为控制栏添加拖拽功能
        controlBar.setOnMousePressed(event -> {
            xOffset[0] = event.getSceneX();
            yOffset[0] = event.getSceneY();
        });
        
        controlBar.setOnMouseDragged(event -> {
            primaryStage.setX(event.getScreenX() - xOffset[0]);
            primaryStage.setY(event.getScreenY() - yOffset[0]);
        });
        
        // 为整个内容区域添加拖拽功能
        contentBox.setOnMousePressed(event -> {
            xOffset[0] = event.getSceneX();
            yOffset[0] = event.getSceneY();
        });
        
        contentBox.setOnMouseDragged(event -> {
            primaryStage.setX(event.getScreenX() - xOffset[0]);
            primaryStage.setY(event.getScreenY() - yOffset[0]);
        });
        
        // 标题和Logo区域
        VBox headerBox = new VBox(10);
        headerBox.setAlignment(Pos.CENTER);
        
        headerBox.setOnMousePressed(event -> {
            xOffset[0] = event.getSceneX();
            yOffset[0] = event.getSceneY();
        });
        
        headerBox.setOnMouseDragged(event -> {
            primaryStage.setX(event.getScreenX() - xOffset[0]);
            primaryStage.setY(event.getScreenY() - yOffset[0]);
        });
        
        // Logo图片
        ImageView logoView = new ImageView(new Image("static/logo.jpg"));
        logoView.setFitHeight(80);
        logoView.setFitWidth(80);
        
        // 使Logo图片为圆形
        Rectangle clip = new Rectangle(80, 80);
        clip.setArcWidth(80);
        clip.setArcHeight(80);
        logoView.setClip(clip);
        
        // 标题
        Label titleLabel = new Label("加入音乐世界");
        titleLabel.setFont(Font.font("Microsoft YaHei", FontWeight.BOLD, 24));
        titleLabel.setTextFill(Color.web("#1db954"));
        
        Label subtitleLabel = new Label("创建您的账户，畅享音乐体验");
        subtitleLabel.setFont(Font.font("Microsoft YaHei", 14));
        subtitleLabel.setTextFill(Color.web("#666666"));
        
        headerBox.getChildren().addAll(logoView, titleLabel, subtitleLabel);
        
        // 输入区域
        GridPane inputGrid = new GridPane();
        inputGrid.setHgap(15);
        inputGrid.setVgap(10);
        inputGrid.setPadding(new Insets(0, 0, 10, 0));
        inputGrid.setAlignment(Pos.CENTER);
        inputGrid.setMaxWidth(400);
        
        // 手机号输入框
        Label phoneLabel = new Label("手机号");
        phoneLabel.setFont(Font.font("Microsoft YaHei", 14));
        phoneLabel.setTextFill(Color.web("#333333"));
        
        phoneField = new TextField();
        phoneField.setPromptText("请输入手机号");
        phoneField.setPrefHeight(40);
        phoneField.setPrefWidth(350);
        styleTextField(phoneField);
        
        // 设置行间距
        int rowOffset = 0; // 设置起始行位置
        int rowGap = 2;   // 设置行间距
        
        inputGrid.add(phoneLabel, 0, rowOffset);
        inputGrid.add(phoneField, 0, rowOffset + 1);
        GridPane.setHgrow(phoneField, Priority.ALWAYS);
        
        // 密码输入框
        Label passLabel = new Label("密码");
        passLabel.setFont(Font.font("Microsoft YaHei", 14));
        passLabel.setTextFill(Color.web("#333333"));
        
        passwordField = new PasswordField();
        passwordField.setPromptText("请输入密码");
        passwordField.setPrefHeight(40);
        passwordField.setPrefWidth(350);
        styleTextField(passwordField);
        
        rowOffset += rowGap + 1;
        inputGrid.add(passLabel, 0, rowOffset);
        inputGrid.add(passwordField, 0, rowOffset + 1);
        
        // 确认密码输入框
        Label confirmPassLabel = new Label("确认密码");
        confirmPassLabel.setFont(Font.font("Microsoft YaHei", 14));
        confirmPassLabel.setTextFill(Color.web("#333333"));
        
        confirmPasswordField = new PasswordField();
        confirmPasswordField.setPromptText("请再次输入密码");
        confirmPasswordField.setPrefHeight(40);
        confirmPasswordField.setPrefWidth(350);
        styleTextField(confirmPasswordField);
        
        rowOffset += rowGap + 1;
        inputGrid.add(confirmPassLabel, 0, rowOffset);
        inputGrid.add(confirmPasswordField, 0, rowOffset + 1);
        
        // 验证码区域
        Label captchaLabel = new Label("验证码");
        captchaLabel.setFont(Font.font("Microsoft YaHei", 14));
        captchaLabel.setTextFill(Color.web("#333333"));
        
        HBox captchaBox = new HBox(10);
        captchaBox.setAlignment(Pos.CENTER_LEFT);
        captchaBox.setPrefWidth(350);
        captchaBox.setMaxWidth(350);
        
        captchaField = new TextField();
        captchaField.setPromptText("请输入验证码");
        captchaField.setPrefHeight(40);
        captchaField.setPrefWidth(210);
        styleTextField(captchaField);
        
        getCaptchaButton = new Button("获取验证码");
        getCaptchaButton.setPrefHeight(40);
        getCaptchaButton.setMinWidth(120);
        getCaptchaButton.setPrefWidth(120);
        styleCaptchaButton(getCaptchaButton);
        
        captchaBox.getChildren().addAll(captchaField, getCaptchaButton);
        captchaBox.setSpacing(10);
        HBox.setHgrow(captchaField, Priority.ALWAYS);
        
        rowOffset += rowGap + 1;
        inputGrid.add(captchaLabel, 0, rowOffset);
        inputGrid.add(captchaBox, 0, rowOffset + 1);
        
        // 按钮区域
        VBox buttonsBox = new VBox(15);
        buttonsBox.setAlignment(Pos.CENTER);
        buttonsBox.setPadding(new Insets(10, 0, 30, 0));
        
        // 注册按钮
        registerButton = new Button("注 册");
        registerButton.setPrefHeight(45);
        registerButton.setPrefWidth(350);
        registerButton.setMaxWidth(350);
        styleRegisterButton(registerButton);
        
        // 返回登录
        HBox loginBox = new HBox(5);
        loginBox.setAlignment(Pos.CENTER);
        loginBox.setPadding(new Insets(5, 0, 20, 0));
        loginBox.setMaxWidth(350);
        loginBox.setPrefWidth(350);
        Label hasAccountLabel = new Label("已有账号?");
        hasAccountLabel.setFont(Font.font("Microsoft YaHei", 12));
        hasAccountLabel.setTextFill(Color.web("#666666"));
        
        backToLoginButton = new Button("返回登录");
        backToLoginButton.setStyle("-fx-background-color: transparent; -fx-text-fill: #1db954; -fx-font-weight: bold; -fx-padding: 0;");
        backToLoginButton.setFont(Font.font("Microsoft YaHei", 12));
        
        loginBox.getChildren().addAll(hasAccountLabel, backToLoginButton);
        
        buttonsBox.getChildren().addAll(registerButton, loginBox);
        
        // 组装所有元素并设置足够空间
        contentBox.getChildren().addAll(controlBar, headerBox, inputGrid, buttonsBox);
        contentBox.setSpacing(15);
        
        // 添加到卡片容器
        cardContainer.getChildren().add(contentBox);
        
        // 设置主布局
        root.setCenter(cardContainer);
        
        // 创建场景
        Scene scene = new Scene(root, 600, 720);
        scene.setFill(Color.TRANSPARENT); // 设置场景透明背景
        
        // 添加CSS样式
        scene.getStylesheets().add("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap");
        
        primaryStage.setScene(scene);
        primaryStage.show();

        setupListeners(primaryStage);
    }

    private void styleTextField(javafx.scene.control.TextInputControl textField) {
        textField.setStyle(
            "-fx-background-color: #f5f5f5;" +
            "-fx-background-radius: 5px;" +
            "-fx-border-color: transparent;" +
            "-fx-padding: 10px;" +
            "-fx-font-size: 14px;"
        );
        
        textField.focusedProperty().addListener((obs, wasFocused, isFocused) -> {
            if (isFocused) {
                textField.setStyle(
                    "-fx-background-color: white;" +
                    "-fx-background-radius: 5px;" +
                    "-fx-border-color: #1db954;" +
                    "-fx-border-width: 2px;" +
                    "-fx-border-radius: 5px;" +
                    "-fx-padding: 10px;" +
                    "-fx-font-size: 14px;"
                );
            } else {
                textField.setStyle(
                    "-fx-background-color: #f5f5f5;" +
                    "-fx-background-radius: 5px;" +
                    "-fx-border-color: transparent;" +
                    "-fx-padding: 10px;" +
                    "-fx-font-size: 14px;"
                );
            }
        });
    }

    private void styleRegisterButton(Button button) {
        button.setStyle(
            "-fx-background-color: #1db954;" +
            "-fx-text-fill: white;" +
            "-fx-font-weight: bold;" +
            "-fx-font-size: 16px;" +
            "-fx-background-radius: 5px;"
        );
        
        button.setOnMouseEntered(e -> 
            button.setStyle(
                "-fx-background-color: #1ed760;" +
                "-fx-text-fill: white;" +
                "-fx-font-weight: bold;" +
                "-fx-font-size: 16px;" +
                "-fx-background-radius: 5px;"
            )
        );
        
        button.setOnMouseExited(e -> 
            button.setStyle(
                "-fx-background-color: #1db954;" +
                "-fx-text-fill: white;" +
                "-fx-font-weight: bold;" +
                "-fx-font-size: 16px;" +
                "-fx-background-radius: 5px;"
            )
        );
        
        button.setOnMousePressed(e -> 
            button.setStyle(
                "-fx-background-color: #1aa34a;" +
                "-fx-text-fill: white;" +
                "-fx-font-weight: bold;" +
                "-fx-font-size: 16px;" +
                "-fx-background-radius: 5px;"
            )
        );
    }
    
    private void styleCaptchaButton(Button button) {
        button.setStyle(
            "-fx-background-color: #ff9800;" +
            "-fx-text-fill: white;" +
            "-fx-font-weight: bold;" +
            "-fx-font-size: 14px;" +
            "-fx-background-radius: 5px;"
        );
        
        button.setOnMouseEntered(e -> 
            button.setStyle(
                "-fx-background-color: #ffab40;" +
                "-fx-text-fill: white;" +
                "-fx-font-weight: bold;" +
                "-fx-font-size: 14px;" +
                "-fx-background-radius: 5px;"
            )
        );
        
        button.setOnMouseExited(e -> 
            button.setStyle(
                "-fx-background-color: #ff9800;" +
                "-fx-text-fill: white;" +
                "-fx-font-weight: bold;" +
                "-fx-font-size: 14px;" +
                "-fx-background-radius: 5px;"
            )
        );
        
        button.setOnMousePressed(e -> 
            button.setStyle(
                "-fx-background-color: #f57c00;" +
                "-fx-text-fill: white;" +
                "-fx-font-weight: bold;" +
                "-fx-font-size: 14px;" +
                "-fx-background-radius: 5px;"
            )
        );
    }

    private void setupListeners(Stage primaryStage) {
        // 获取验证码事件
        getCaptchaButton.setOnAction(e -> {
            String phone = phoneField.getText().trim();
            if (phone.isEmpty() || !phone.matches("^1[3-9]\\d{9}$")) {
                showAlert("提示", "请输入有效的手机号！", Alert.AlertType.WARNING);
                return;
            }
            
            // 检查是否可以获取新验证码
            if (redisUtil.get(RedisConstant.PHONE_CODE_PREFIX + phone) != null) {
                long expire = 0;
                try {
                    expire = Long.parseLong(redisUtil.getExpire(RedisConstant.PHONE_CODE_PREFIX + phone));
                    showAlert("提示", "请再" + expire + "秒后获取验证码！", Alert.AlertType.WARNING);
                } catch (Exception ex) {
                    log.error("获取验证码过期时间异常", ex);
                    showAlert("提示", "获取验证码失败，请稍后再试", Alert.AlertType.WARNING);
                }
                return;
            }
            
            // 生成新的验证码
            currentCaptcha = RandomStringUtil.getCaptchaCode();
            redisUtil.setNx(RedisConstant.PHONE_CODE_PREFIX + phone, currentCaptcha, Long.valueOf(RedisConstant.CODE_ONE_MINUTES));
            
            // 在按钮上显示验证码
            getCaptchaButton.setText(currentCaptcha);
            getCaptchaButton.setStyle(
                "-fx-background-color: #1db954;" + // 使用绿色背景表示已获取验证码
                "-fx-text-fill: white;" +
                "-fx-font-weight: bold;" +
                "-fx-font-size: 16px;" + // 增大字体以突出显示验证码
                "-fx-background-radius: 5px;"
            );
            
            // 禁用按钮60秒
            getCaptchaButton.setDisable(true);
            
            // 创建60秒倒计时
            Timeline timeline = new Timeline();
            timeline.setCycleCount(60);
            final int[] remainSeconds = {60}; // 使用数组存储倒计时秒数，以便在lambda中修改
            
            KeyFrame keyFrame = new KeyFrame(Duration.seconds(1), event -> {
                remainSeconds[0]--;
                try {
                    // 尝试从Redis获取过期时间，如果失败则使用本地倒计时
                    long remainTime = Long.parseLong(redisUtil.getExpire(RedisConstant.PHONE_CODE_PREFIX + phone));
                    if (remainTime > 0) {
                        getCaptchaButton.setText(currentCaptcha + " (" + remainTime + "s)");
                    } else {
                        resetCaptchaButton(timeline);
                    }
                } catch (Exception ex) {
                    // Redis获取失败时使用本地倒计时
                    if (remainSeconds[0] > 0) {
                        getCaptchaButton.setText(currentCaptcha + " (" + remainSeconds[0] + "s)");
                    } else {
                        resetCaptchaButton(timeline);
                    }
                }
            });
            
            timeline.getKeyFrames().add(keyFrame);
            timeline.play();
            
            // 可选：也在控制台显示验证码，方便测试
            log.info("验证码已发送：{}", currentCaptcha);
        });

        // 注册按钮事件
        registerButton.setOnAction(e -> {
            String phone = phoneField.getText();
            String password = passwordField.getText();
            String confirmPassword = confirmPasswordField.getText();
            String inputCaptcha = captchaField.getText();

            if (phone.isEmpty() || password.isEmpty() || confirmPassword.isEmpty() || inputCaptcha.isEmpty()) {
                showAlert("错误", "所有字段都不能为空！", Alert.AlertType.ERROR);
                return;
            }
            if (!password.equals(confirmPassword)) {
                showAlert("错误", "两次输入的密码不一致！", Alert.AlertType.ERROR);
                return;
            }
            
            // 从Redis获取验证码
            String storedCaptcha = (String) redisUtil.get(RedisConstant.PHONE_CODE_PREFIX + phone);
            if (storedCaptcha == null) {
                showAlert("错误", "验证码已失效！请重新获取", Alert.AlertType.ERROR);
                return;
            }
            
            // 验证码比较
            if (!inputCaptcha.equalsIgnoreCase(storedCaptcha)) {
                showAlert("错误", "验证码错误！", Alert.AlertType.ERROR);
                return;
            }

            UsersReq usersReq = new UsersReq(phone, password, inputCaptcha);
            log.info("用户尝试注册：{}", JSON.toJSONString(usersReq));
            Result<Boolean> result = usersController.register(usersReq);

            if (Boolean.TRUE.equals(result.getData())) {
                showAlert("提示", "注册成功！", Alert.AlertType.INFORMATION);
                primaryStage.close();
                try {
                    Stage loginStage = new Stage();
                    LoginFxUi loginFxUi = SpringContextUtil.getBean(LoginFxUi.class);
                    loginFxUi.start(loginStage);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            } else {
                showAlert("错误", "注册失败，请重试。", Alert.AlertType.ERROR);
            }
        });

        // 返回登录按钮事件
        backToLoginButton.setOnAction(e -> {
            primaryStage.close();
            try {
                Stage loginStage = new Stage();
                LoginFxUi loginFxUi = SpringContextUtil.getBean(LoginFxUi.class);
                loginFxUi.start(loginStage);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        });
    }

    // 重置验证码按钮状态
    private void resetCaptchaButton(Timeline timeline) {
        timeline.stop();
        getCaptchaButton.setText("获取验证码");
        styleCaptchaButton(getCaptchaButton);
        getCaptchaButton.setDisable(false);
    }

    private void showAlert(String title, String message, Alert.AlertType type) {
        Alert alert = new Alert(type);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
}
